<template>
  <div class="container">
    <canvas ref="canvasRef" width="400" height="30"></canvas>
    <div class="message">{{ message }}</div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
let centerX = 0
let centerY = 0
const canvasRef = ref(null)

const props = defineProps({
  step: {
    type: Number,
    default: 0.2
  },
  centre: {
    type: Number,
    default: 50
  },
  message: {
    type: String,
    default: 'RUDDER'
  }
})

let nowIndex = props.centre
let execute = false
let interval = null

const addIndex = () => {
  if (execute) {
    return
  }

  // 清除当前定时器
  if (interval !== null) {
    clearInterval(interval)
    interval = null
  }

  interval = setInterval(() => {
    if (nowIndex + props.step <= 90) {
      drawDynamicIndex(true)
    } else {
      stop()
    }
  }, 100)

  execute = true
}

const stop = () => {
  execute = false
  if (interval !== null) {
    clearInterval(interval)
    interval = null
  }
}

const drawDynamicIndex = (params) => {
  const canvas = canvasRef.value
  if (canvas.getContext && execute) {
    const ctx = canvas.getContext('2d')
    drawCanvas(ctx, canvas.width, canvas.height)
    nowIndex = params ? nowIndex + props.step : nowIndex - props.step
    drawIndex(ctx, canvas.width, canvas.height)
    // 递归调用，更新下一帧
    if (nowIndex - props.step >= 10 && nowIndex + props.step <= 90) {
      requestAnimationFrame(() => drawDynamicIndex(params))
    } else {
      stop()
    }
  }
}

const minusIndex = () => {
  if (execute) {
    return
  }

  // 清除当前定时器
  if (interval !== null) {
    clearInterval(interval)
    interval = null
  }

  interval = setInterval(() => {
    if (nowIndex - props.step >= 10) {
      drawDynamicIndex(false)
    } else {
      stop()
    }
  }, 100)

  execute = true
}

onMounted(() => {
  const canvas = canvasRef.value
  if (canvas.getContext) {
    const ctx = canvas.getContext('2d')
    centerX = canvas.width * 0.5
    centerY = canvas.height * 0.5
    drawCanvas(ctx, canvas.width, canvas.height)
    drawIndex(ctx, canvas.width, canvas.height)
  }
})

const drawIndex = (ctx, width, height) => {
  ctx.beginPath()
  ctx.moveTo((centerX * nowIndex) / 100, centerY)
  ctx.lineTo(
    (centerX * nowIndex) / 100 - 20 * Math.sin(Math.PI / 12),
    centerY + 20 * Math.cos(Math.PI / 12)
  )
  ctx.lineTo(
    (centerX * nowIndex) / 100 + 20 * Math.sin(Math.PI / 12),
    centerY + 20 * Math.cos(Math.PI / 12)
  )
  ctx.fillStyle = 'white'
  ctx.fill()
  ctx.closePath()
}

const drawCanvas = (ctx, width, height) => {
  ctx.clearRect(0, 0, width, height)
  ctx.beginPath()
  ctx.moveTo(centerX * 0.1, centerY)
  ctx.lineTo(centerX * 0.9, centerY)
  ctx.lineWidth = 2
  ctx.strokeStyle = 'white'
  ctx.stroke()
  ctx.moveTo(centerX * 0.1, centerY - 4)
  ctx.lineTo(centerX * 0.1, centerY + 4)
  ctx.lineWidth = 2
  ctx.strokeStyle = 'white'
  ctx.stroke()
  ctx.moveTo(centerX * 0.9, centerY - 4)
  ctx.lineTo(centerX * 0.9, centerY + 4)
  ctx.lineWidth = 2
  ctx.strokeStyle = 'white'
  ctx.stroke()
  ctx.moveTo(centerX * 0.5, centerY - 4)
  ctx.lineTo(centerX * 0.5, centerY + 4)
  ctx.lineWidth = 2
  ctx.strokeStyle = 'white'
  ctx.stroke()
  ctx.closePath()
}

defineExpose({
  addIndex,
  minusIndex,
  stop
})
</script>

<style scoped>
.container {
  position: relative;
  width: 400px;
  height: 30px;
  z-index: 10; /* 保证该元素位于背景图片的上层 */
}
.message {
  position: relative;
  top: -10px;
  left: -98px;
  text-align: center;
  color: rgb(8, 214, 255);
  font-weight: 600;
}
</style>
